﻿// Decompiled with JetBrains decompiler
// Type: Microsoft.InfoCards.GlobalId
// Assembly: infocard, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
// MVID: 8E14765A-6610-409A-BA36-099A0642905D
// Assembly location: E:\git\ALLIDA\windll\infocard.exe

using Microsoft.InfoCards.Diagnostics;
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;

namespace Microsoft.InfoCards
{
  [StructLayout(LayoutKind.Explicit, Size = 16)]
  internal struct GlobalId
  {
    public static readonly GlobalId Empty = (GlobalId) Guid.Empty;
    private static readonly byte[] HASHPREFIX = new byte[16]
    {
      (byte) 126,
      (byte) 85,
      (byte) 219,
      (byte) 17,
      (byte) 52,
      (byte) 221,
      (byte) 70,
      (byte) 150,
      (byte) 168,
      (byte) 123,
      (byte) 15,
      (byte) 254,
      (byte) 196,
      (byte) 77,
      (byte) 155,
      (byte) 168
    };
    public const int StructSize = 16;

    public GlobalId(byte[] guidBytes)
    {
      this = new GlobalId(new Guid(guidBytes));
    }

    public unsafe GlobalId(Guid guid)
    {
      fixed (GlobalId* globalIdPtr = &this)
        *globalIdPtr = (GlobalId) guid;
    }

    public byte[] ToByteArray()
    {
      return (Guid) this.ToByteArray();
    }

    public override int GetHashCode()
    {
      return (Guid) this.GetHashCode();
    }

    public override bool Equals(object obj)
    {
      if (obj is GlobalId || obj is Guid)
        return (GlobalId) obj == this;
      return false;
    }

    public override string ToString()
    {
      return (Guid) this.ToString("D");
    }

    public static bool operator !=(GlobalId a, GlobalId b)
    {
      return !(a == b);
    }

    public static unsafe bool operator ==(GlobalId a, GlobalId b)
    {
      byte* numPtr1 = (byte*) &a;
      byte* numPtr2 = (byte*) &b;
      for (int index = 0; index < sizeof (GlobalId); ++index)
      {
        if ((int) numPtr1[index] != (int) numPtr2[index])
          return false;
      }
      return true;
    }

    public static unsafe implicit operator Guid(GlobalId id)
    {
      return *(Guid*) &id;
    }

    public static unsafe implicit operator GlobalId(Guid guid)
    {
      return *(GlobalId*) &guid;
    }

    public static GlobalId DeriveFrom(string value)
    {
      if (string.IsNullOrEmpty(value))
        throw InfoCardTrace.ThrowHelperArgumentNull(nameof (value));
      value = value.Trim();
      value = value.ToLower(CultureInfo.InvariantCulture);
      using (SHA256Managed shA256Managed = new SHA256Managed())
      {
        byte[] numArray = new byte[Encoding.Unicode.GetByteCount(value) + GlobalId.HASHPREFIX.Length];
        Array.Copy((Array) GlobalId.HASHPREFIX, 0, (Array) numArray, 0, GlobalId.HASHPREFIX.Length);
        Encoding.Unicode.GetBytes(value, 0, value.Length, numArray, GlobalId.HASHPREFIX.Length);
        byte[] hash = shA256Managed.ComputeHash(numArray);
        return new GlobalId(new byte[16]
        {
          hash[3],
          hash[2],
          hash[1],
          hash[0],
          hash[5],
          hash[4],
          hash[7],
          (byte) ((int) hash[6] & 15 | 48),
          (byte) ((int) hash[8] & 63 | 128),
          hash[9],
          hash[10],
          hash[11],
          hash[12],
          hash[13],
          hash[14],
          hash[15]
        });
      }
    }
  }
}
